/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */


use sea_orm::entity::prelude::*;
use sea_orm::FromQueryResult;
use serde::Serialize;
use serde_json::Value;
use crate::entities::restful_model::cert_request::AddCertRequest;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Default)]
#[sea_orm(table_name = "t_cert_info")]
pub struct Model {
    #[sea_orm(column_name = "id", primary_key, auto_increment = false)]
    pub id: String,
    #[sea_orm(column_name = "serial_num")]
    pub serial_num: Option<String>,
    #[sea_orm(column_name = "user_id")]
    pub user_id: Option<String>,
    #[sea_orm(column_type = "Json")]
    #[sea_orm(column_name = "type")]
    pub cert_type: Option<Value>,
    #[sea_orm(column_name = "name", unique)]
    pub name: Option<String>,
    #[sea_orm(column_name = "issuer")]
    pub issuer: Option<String>,
    #[sea_orm(column_name = "owner")]
    pub owner: Option<String>,
    #[sea_orm(column_name = "cert_info")]
    pub cert_info: Option<Vec<u8>>,
    #[sea_orm(column_name = "is_default")]
    pub is_default: Option<bool>,
    #[sea_orm(column_name = "description")]
    pub description: Option<String>,
    #[sea_orm(column_name = "version")]
    pub version: Option<i32>,
    #[sea_orm(column_name = "create_time")]
    pub create_time: Option<i64>,
    #[sea_orm(column_name = "update_time")]
    pub update_time: Option<i64>,
    #[sea_orm(column_name = "signature")]
    pub signature: Option<Vec<u8>>,
    #[sea_orm(column_name = "key_version")]
    pub key_version: Option<String>,
    #[sea_orm(column_name = "key_id")]
    pub key_id: Option<String>,
    #[sea_orm(column_name = "valid_code")]
    pub valid_code: Option<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
    #[sea_orm(has_one = "super::cert_revoked_list::Entity")]
    CertRevokedList,
}

impl Related<super::cert_revoked_list::Entity> for Entity {
    fn to() -> RelationDef {
        Relation::CertRevokedList.def()
    }
}
impl ActiveModelBehavior for ActiveModel {}

#[derive(FromQueryResult)]
pub struct SimpleInfo {
    pub id: String,
    pub name: Option<String>,
    pub version: Option<i32>,
}

impl ActiveModel {
    pub fn new_from_cert_data(
        cert_id: String,
        serial_num: String,
        user_id: String,
        cert_type: serde_json::Value,
        name: String,
        issuer: String,
        owner: String,
        cert_content: Vec<u8>,
        is_default: Option<bool>,
        description: Option<String>,
        timestamp_millis: i64,
        signature: Option<Vec<u8>>,
        key_version: Option<String>,
        valid_code: Option<i32>,
    ) -> Self {
        use sea_orm::ActiveValue;
        
        Self {
            id: ActiveValue::Set(cert_id),
            serial_num: ActiveValue::Set(Some(serial_num)),
            user_id: ActiveValue::Set(Some(user_id)),
            cert_type: ActiveValue::Set(Some(cert_type)),
            name: ActiveValue::Set(Some(name)),
            issuer: ActiveValue::Set(Some(issuer)),
            owner: ActiveValue::Set(Some(owner)),
            cert_info: ActiveValue::Set(Some(cert_content)),
            is_default: ActiveValue::Set(is_default),
            description: ActiveValue::Set(description),
            version: ActiveValue::Set(Some(1)),
            create_time: ActiveValue::Set(Some(timestamp_millis)),
            update_time: ActiveValue::Set(Some(timestamp_millis)),
            signature: ActiveValue::Set(signature),
            key_version: ActiveValue::Set(key_version),
            valid_code: ActiveValue::Set(valid_code),
            ..Default::default()
        }
    }
}

impl Model {
    /// Create Model from AddCertRequest for signature generation
    pub fn from_add_cert_request_for_signature(
        request: &AddCertRequest,
        cert_id: String,
        serial_num: String,
        user_id: String,
        issuer: String,
        owner: String,
        content: Vec<u8>,
        timestamp_millis: i64,
    ) -> Self {
        Self {
            id: cert_id,
            serial_num: Some(serial_num),
            user_id: Some(user_id),
            cert_type: Some(serde_json::json!(request.cert_type)),
            name: Some(request.name.clone()),
            issuer: Some(issuer),
            owner: Some(owner),
            cert_info: Some(content),
            is_default: request.is_default.or(Some(false)),
            description: request.description.clone(),
            version: Some(1),
            create_time: Some(timestamp_millis),
            update_time: Some(timestamp_millis),
            ..Default::default()
        }
    }
}
